/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.cmti.skeleton.web.shiro;

import com.cmti.commons.entity.AuthenticationInfo;
import com.cmti.commons.util.RequestEndSystemInfo;
import com.cmti.skeleton.dto.SysLogDto;
import com.cmti.skeleton.entity.SysLog;
import com.cmti.skeleton.service.SysLogService;
import com.cmti.skeleton.web.SysLogInterceptor;
import java.util.Date;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.SessionException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 *
 * @author : yaohk
 */
@Service
public class SystemLogoutFilter extends LogoutFilter {

    private final Log log = LogFactory.getLog(getClass());
    @Autowired
    SysLogService sysLogService;

    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        AuthenticationInfo authInfo = (AuthenticationInfo) SecurityUtils.getSubject().getPrincipal();
        Subject subject = getSubject(request, response);
        String redirectUrl = getRedirectUrl(request, response, subject);
        // 记录日志
        SysLogDto sysLog = new SysLogDto();
        sysLog.setType(SysLog.TYPE_SYSTEM);
        sysLog.setOperTime(new Date());
        try {
            subject.logout();//登出
            if (authInfo != null) {
                sysLog.setOperatorId(authInfo.getId().intValue());
                sysLog.setLogContent("用户 " + authInfo.getAccount() + "（" + authInfo.getName() + "）登出系统");
            } else {
                // 各种原因登出失败，比如session已经过期
                sysLog.setOperatorId(0);
                sysLog.setLogContent("登出系统异常: 用户会话已过期!");
                sysLog.setResult(SysLog.RESULT_FAIL);
            }
        } catch (SessionException se) {
            sysLog.setOperatorId(0);
            sysLog.setLogContent("登出系统异常: 用户会话已过期!");
            sysLog.setResult(SysLog.RESULT_FAIL);
            log.error("登出失败" + se);
        } finally {
            sysLog.setIp(RequestEndSystemInfo.getIpAddr((HttpServletRequest) request));
            sysLogService.add(sysLog);
            SysLogInterceptor.logSysLogDetail(sysLog, (HttpServletRequest) request);
        }
        issueRedirect(request, response, redirectUrl);
        return false;
    }

}
